<template>
    <el-container class="container">
        <div class="breadcrumb">
                <el-breadcrumb separator="/">
                    <el-breadcrumb-item :to="{ path: '/' }"><el-icon><House /></el-icon></el-breadcrumb-item>
                    <el-breadcrumb-item >Depmap Explore Data</el-breadcrumb-item>
                </el-breadcrumb>
            </div>
        <Analysis />
        <div class="searchbar" v-if="isMobile">
            <div style="display: flex; justify-content: space-between;">
                <el-button type="primary" style="margin-left: 16px" @click="drawer = true">
                    Search Conditions
                </el-button>
            </div>
            <el-drawer
                v-model="drawer"
                direction="ltr"
                size="50%"
                >
                <KeepAlive>
                    <SearchColumn 
                        :searchItems="searchItems" 
                        :updateTable="updateTable" 
                        :showDownload=false 
                        :initSelectedValues="initSelectedValues"
                        page="depmap" 
                        />
                </KeepAlive>   
            </el-drawer>
        </div>
        <div style="margin-top: 20px;" v-else>
            <KeepAlive>
                <SearchColumn 
                    :searchItems="searchItems" 
                    :updateTable="updateTable" 
                    :initSelectedValues="initSelectedValues"
                    :showDownload=false
                    page="depmap"  
                    />
            </KeepAlive>
        </div>
        <div class="main" >
            <div class="table-container">
                <el-table 
                    :data="tableData" 
                    height="600" 
                    stripe
                    @sort-change="handleSortChange"
                >
                    <el-table-column prop="fields.DataType" label="DataType" sortable min-width="110">
                        <template #default="scope">
                            <div v-if="scope.row.fields.DataType === 'depmap_diff_gene_analysis'">
                                <a class="data-type" @click="checkDetail(scope.row)">Gene</a>
                            </div>
                            <div v-if="scope.row.fields.DataType === 'depmap_diff_drug_analysis'">
                                <a class="data-type" @click="checkDetail(scope.row)">Drug</a>
                            </div>
                            <div v-if="scope.row.fields.DataType === 'depmap_diff_expression_analysis'">
                                <a class="data-type" @click="checkDetail(scope.row)">Expression</a>
                            </div>
                            <div v-if="scope.row.fields.DataType === 'depmap_diff_protein_analysis'">
                                <a class="data-type" @click="checkDetail(scope.row)">Protein</a>
                            </div>
                            <div v-if="scope.row.fields.DataType === 'depmap_diff_methylation_analysis'">
                                <a class="data-type" @click="checkDetail(scope.row)">Methylation</a>
                            </div>
                        </template>
                    </el-table-column>
                    <el-table-column prop="fields.Target" v-if="showGene" label="Gene Target" sortable  min-width="150"/>
                    <el-table-column prop="fields.Target" v-else label="Drug Target" sortable min-width="150" />
                    <el-table-column prop="fields.TumorType" label="TumorType" sortable min-width="150" />
                    <el-table-column prop="fields.P_Value" label="Limma.P.Value" :formatter="formatDecimal" sortable  min-width="150"/>
                    <el-table-column prop="fields.Wilcox_P_Value" label="Wilcoxon.P.Value" width="160" sortable :formatter="formatDecimal"/>
                    <el-table-column prop="fields.logFC" label="logFC" :formatter="formatDecimal" sortable min-width="110" />
                    <el-table-column prop="fields.AveExpr" label="AveExpr" :formatter="formatDecimal" sortable min-width="110" />
                    <!-- <el-table-column prop="fields.t" label="t" :formatter="formatDecimal" width="160"/> -->
                    <!-- <el-table-column prop="fields.adj_P_Val" label="adj.P.Val" :formatter="formatDecimal" sortable width="160"/> -->
                    <!-- <el-table-column prop="fields.B" label="B" :formatter="formatDecimal" width="160"/> -->
                    <el-table-column prop="fields.Protein" label="Protein" sortable v-if="showGene" min-width="160"/>
                    <el-table-column prop="fields.targetgene" label="Target Gene" show-overflow-tooltip sortable v-if="!showGene" min-width="200"/>
                    <el-table-column prop="fields.MOA" label="MOA" show-overflow-tooltip v-if="!showGene" min-width="160" sortable />
                    <el-table-column prop="fields.Synonyms" label="Synonyms" v-if="!showGene" sortable min-width="160"/>
                </el-table>
            </div>
            <div class="pagination-container">
                <el-pagination
                    v-model:current-page="currentPage"
                    :page-size="currentPageSize"
                    background
                    :page-sizes="[10, 20, 50, 100]"
                    layout="total, sizes, prev, pager, next, jumper"
                    :total="total"
                    @size-change="handleSizeChange"
                    @current-change="handleCurrentChange"
                />
            </div>
        </div>
    </el-container>
</template>

<script setup lang="ts" name="DepmapExplore">
    import { onBeforeMount, ref, watch } from 'vue';
    import { get, post } from '../../axios/api';
    import SearchColumn from '@/components/SearchColumn.vue'
    import Analysis from './Analysis.vue'
    import { ElMessage, } from 'element-plus'
    import { useRoute, useRouter } from 'vue-router';
    import { ElLoading } from 'element-plus'
    import { formatDecimal } from './options/utils'

    let loading = ref(true)
    let tableData = ref([]);
    let total = ref(0)
    let currentPage = ref(1)
    let currentPageSize = ref(10)
    let selectedValues = ref();
    let showGene = ref(true)
    let isSorted = ref(false)
    let sortedProp = ref('P_Value')
    let sortedOrder = ref('ascending')
    const initSortedBy = 'P_Value'
    const initSortedOrder = 'ascending' 
    let isMobile = ref(window.innerWidth <= 768)
    const drawer = ref(false)
    let loadingInstance:any = null
    let initSelectedValues = ref();

    const router = useRouter()
    const route = useRoute()
    const dataTypeIndex: any = {
        'gene': 'depmap_diff_gene_analysis',
        'exp': 'depmap_diff_expression_analysis',
        'drug': 'depmap_diff_drug_analysis',
        'protein': 'depmap_diff_protein_analysis',
        'methylation': 'depmap_diff_methylation_analysis'
    }

    let searchItems:any = ref([
        {
            type: 'tab-multi-select', value: 'GeneTarget',
            tabs: [
                {label: 'Gene', value: 'GeneTarget', options: [], type: 'tab-multi-select', isChosen: true},
                {label: 'Drug', value: 'DrugTarget', options: [], type: 'tab-multi-select', isChosen: false},
            ]
        },
        {label: 'TumorType', value: 'TumorType', options: [], type: 'multi-select'}
    ])

    async function handleSortChange(ele:any) {
        isSorted.value = true
        sortedProp.value = ele.prop.split('.')[1]
        sortedOrder.value = ele.order
        if (selectedValues.value) {
            getData(currentPage.value, currentPageSize.value, selectedValues.value ,sortedProp.value, sortedOrder.value)
        } else {
            getData(currentPage.value, currentPageSize.value, {} ,sortedProp.value, sortedOrder.value)
        }
    }

    async function handleCurrentChange(val: number) {
        currentPage.value = val
        if (isSorted) {
            getData(val, currentPageSize.value, selectedValues.value, sortedProp.value, sortedOrder.value)
        } else {
            getData(val, currentPageSize.value, selectedValues.value, initSortedBy, initSortedOrder)
        }
    }

    async function handleSizeChange(val: number) {
        currentPageSize.value = val
        if (isSorted) {
            getData(currentPage.value, val, selectedValues.value, sortedProp.value, sortedOrder.value)
        } else {
            getData(currentPage.value, val, selectedValues.value, initSortedBy, initSortedOrder)
        }
    }

    async function handleOption(items: any) {
        loading.value = true
        const promises: Promise<any>[] = [];
        for (let item of items) {
            // 分为一般情况和tabs情况，tabs情况需要再来一层
            if (item.type === 'tab-multi-select') {
                for (let tab of item.tabs) {
                    promises.push(getOptions(tab, item.tabs, 'tab'));
                }
            } else {
                promises.push(getOptions(item, searchItems, 'single'));
            }
        }
        await Promise.all(promises);
        loadingInstance.close()
    }

    async function getOptions(item: any, items: any, type:string) {
        let res:any = {}
        try {
            let queryData = {
                option: item.value, 
                params: selectedValues.value ? selectedValues.value : {},
                showGene: showGene.value
            }
            res = await post('/get_wald_result_options/', queryData)
        } catch (error:any) {
            ElMessage({
                message: error,
                type: 'error',
            })
        }
        if (res && res.success) {
            loading.value = false
            let target:any = {}
            if (type ==='tab') {
                target = items.find((el: any) => el.value === item.value)
            } else {
                target = items.value.find((el: any) => el.value === item.value)
            }
            target.options = res.data
        } else {
            loading.value = false
            loadingInstance.close()
            ElMessage({
                message: res.msg ? res.msg : "An error occured",
                type: 'error',
            })
            return
        }
    }
    
    /*
        搜索逻辑由两部分构成： datatype和下拉框
        1、只选datatype： 所有数据直接显示
        2、datatype和下拉框一一对应选择，即选了datatype还选了对应的下拉框限制条件：按照限制条件显示对应datatype的数据
        3、有的datatype没选数据：那就显示所有
        1.1 去掉datatype
    */
    async function getData(page: number, page_size: number, params: any, sort_by: any, sort_order: any) {
        let res:any = {}
        let data = {
            page,
            page_size,
            params,
            sort_by,
            sort_order
        }
        loading.value = true
        try {
            res = await post('/get_wald_result_data/', data)
        } catch (error:any) {
            loadingInstance.close()
            ElMessage({
                message: error,
                type: 'error',
            })
        }
        if (res && res.success) {
            loadingInstance.close()
            tableData.value = res.list
            currentPage.value = res.page
            total.value = res.total
        } else {
            loadingInstance.close()
            ElMessage({
                message: res.msg,
                type: 'error',
            })
        }
    }

    function updateTable(val: any) {
        loadingInstance = ElLoading.service({fullscreen: true})
        showGene.value = 'DrugTarget' in val ? false : true
        // 此处查询条件需要有两部分，一部分是datatype，一部分是下拉框选项
        selectedValues.value = val
        if (isSorted) {
            getData(currentPage.value, currentPageSize.value, val, sortedProp.value, sortedOrder.value)
        } else {
            getData(currentPage.value, currentPageSize.value, val, initSortedBy, initSortedOrder)
        }
    }

    function checkDetail(row:any) {
        router.push({
            name:'depDetail',
            params: {
                dataType: row.fields.DataType,
                Target: row.fields.Target,
                TumorType: row.fields.TumorType
            }
        })
    }

    watch(drawer, (newValue:any) => {
        if (newValue) {
            handleOption(searchItems.value)
        }
    }, {deep: true})

    onBeforeMount(() => {
        loadingInstance = ElLoading.service({fullscreen: true})
        handleOption(searchItems.value)
        const dataType:any = route.params.dataType

        const strategies: any = {
            targetNotNone_tumortypeNone: () => {
                if (dataType === 'drug') {
                    initSelectedValues.value = {
                        DrugTarget: [route.params.target],
                    }
                    selectedValues.value = {
                        DrugTarget: [route.params.target],
                        DataType: dataTypeIndex[dataType]
                    }
                    searchItems.value[0].tabs[0].isChosen = false
                    searchItems.value[0].tabs[1].isChosen = true
                    showGene.value = false
                } else {
                    initSelectedValues.value = {
                        Target: [route.params.target],
                    }
                    selectedValues.value = {
                        Target: [route.params.target],
                        DataType: dataTypeIndex[dataType]
                    }
                    searchItems.value[0].tabs[0].isChosen = true
                    searchItems.value[0].tabs[1].isChosen = false
                    showGene.value = true
                }
                getData(currentPage.value, currentPageSize.value, selectedValues.value, initSortedBy, initSortedOrder)
            },
            targetNone_tumortypeNotNone: () => {
                if (dataType === 'drug') {
                    initSelectedValues.value = {
                        DrugTarget: [],
                        TumorType: [route.params.tumortype],
                    }
                    selectedValues.value = {
                        DrugTarget: [],
                        TumorType: [route.params.tumortype],
                        DataType: dataTypeIndex[dataType]
                    }
                    searchItems.value[0].tabs[0].isChosen = false
                    searchItems.value[0].tabs[1].isChosen = true
                    showGene.value = false
                } else {
                    initSelectedValues.value = {
                        TumorType: [route.params.tumortype]
                    }
                    selectedValues.value = {
                        TumorType: [route.params.tumortype],
                        DataType: dataTypeIndex[dataType]
                    }
                    searchItems.value[0].tabs[0].isChosen = true
                    searchItems.value[0].tabs[1].isChosen = false
                    showGene.value = true
                }
                getData(currentPage.value, currentPageSize.value, selectedValues.value, initSortedBy, initSortedOrder)
            },
            targetNotNone_tumortypeNotNone: () => {
                if (dataType === 'drug') {
                    initSelectedValues.value = {
                        DrugTarget: [route.params.target],
                        TumorType: [route.params.tumortype]
                    }
                    selectedValues.value = {
                        DrugTarget: [route.params.target],
                        TumorType: [route.params.tumortype],
                        DataType: dataTypeIndex[dataType]
                    }
                    searchItems.value[0].tabs[0].isChosen = false
                    searchItems.value[0].tabs[1].isChosen = true
                    showGene.value = false
                } else {
                    initSelectedValues.value = {
                        Target: [route.params.target],
                        TumorType: [route.params.tumortype]
                    }
                    selectedValues.value = {
                        Target: [route.params.target],
                        TumorType: [route.params.tumortype],
                        DataType: dataTypeIndex[dataType]
                    }
                    searchItems.value[0].tabs[0].isChosen = true
                    searchItems.value[0].tabs[1].isChosen = false
                    showGene.value = true
                }
                getData(currentPage.value, currentPageSize.value, selectedValues.value, initSortedBy, initSortedOrder)
            },
            default: () => {
                getData(currentPage.value, currentPageSize.value, {}, initSortedBy, initSortedOrder);
            }
        };

        const conditionKey:string = `${route.params.target !== 'none' ? 'targetNotNone' : 'targetNone'}_${route.params.tumortype !== 'none' ? 'tumortypeNotNone' : 'tumortypeNone'}`;
        (strategies[conditionKey] || strategies.default)();
    })
</script>

<style scoped>
    .aside{
        width: 20%;
        background-color: #f5f5f5;
        display: flex;
        flex-direction: column;
        border-radius: 4px;
    }
    .breadcrumb {
        margin: 7px 0px;
    }
    .pagination-container {
        margin: 20px 10px;
        display: flex;
        justify-content: center;
    }

    a {
        color: dodgerblue
    }

    a:hover {
        color: rgb(24, 188, 146);
    }

    .table-container{
        margin: 10px 0px;
        display: flex;
        justify-content: center;
        border-radius: 4px;
        background-color: white;
    }

    .data-type {
        cursor: pointer;
    }

    .container {
        width: 100%;
        display: flex;
        flex-direction: column;
    }

    .searchbar {
        width: 100%;
        display: block;
    }

    @media screen and (max-width: 768px) {
        .container {
            width: 100%;
            display: flex;
            flex-wrap: wrap;
        }
    }
</style>